# https://www.liaoxuefeng.com/wiki/1016959663602400/1017801397501728
# 访问数据库
# SQL教程：https://www.liaoxuefeng.com/wiki/1177760294764384
# 使用SQLite
# SQLite是一种嵌入式数据库，它的数据库就是一个文件。由于SQLite本身是C写的，而且体积很小，所以，经常被集成到各种应用程序中，甚至在iOS和Android的App中都可以集成。Python就内置了SQLite3，所以，在Python中使用SQLite，不需要安装任何东西，直接使用。

'''
    表是数据库中存放关系数据的集合，一个数据库里面通常都包含多个表，比如学生的表，班级的表，学校的表，等等。表和表之间通过外键关联。
    要操作关系数据库，首先需要连接到数据库，一个数据库连接称为Connection；
    连接到数据库后，需要打开游标，称之为Cursor，通过Cursor执行SQL语句，然后，获得执行结果。
    Python定义了一套操作数据库的API接口，任何数据库要连接到Python，只需要提供符合Python标准的数据库驱动即可。
'''
# 由于SQLite的驱动内置在Python标准库中，所以我们可以直接来操作SQLite数据库。
# 导入SQLite驱动:
import os
import sqlite3
# 连接到SQLite数据库
# 数据库文件是test.db
# 如果文件不存在，会自动在当前目录创建:
conn = sqlite3.connect('test.db')
# 创建一个Cursor:
cursor = conn.cursor()
# 执行一条SQL语句，创建user表:
print(cursor.execute(
    'create table user (id int(20) primary key, name varchar(20))'))
# 继续执行一条SQL语句，插入一条记录:
print(cursor.execute('insert into user (id, name) values (\'1\', \'Daniel\')'))
# 通过rowcount获得插入的行数:
print(cursor.rowcount)
# 关闭Cursor:
cursor.close()
# 提交事务:
conn.commit()
# 关闭Connection:
conn.close()
# 我们再试试查询记录：
conn = sqlite3.connect('test.db')
cursor = conn.cursor()
# 执行查询语句:
print(cursor.execute('select * from user where id=?', ('1',)))
# 获得查询结果集:
values = cursor.fetchall()
print(values)
cursor.close()
conn.close()
# 使用Python的DB-API时，只要搞清楚Connection和Cursor对象，打开后一定记得关闭，就可以放心地使用。否则，资源就会泄露
# 使用Cursor对象执行insert，update，delete语句时，执行结果由rowcount返回影响的行数，就可以拿到执行结果。
# 使用Cursor对象执行select语句时，通过fetchall()可以拿到结果集。结果集是一个list，每个元素都是一个tuple，对应一行记录。
# 如果SQL语句带有参数，那么需要把参数按照位置传递给execute()方法，有几个?占位符就必须对应几个参数，例如：
# cursor.execute('select * from user where name=? and pwd=?', ('abc', 'password'))

# 练习：请编写函数，在Sqlite中根据分数段查找指定的名字：
# https://www.136.la/python/show-15631.html
# https://www.dazhuanlan.com/2020/01/06/5e12b2bcd7afc/
# coding=utf-8
# -*- coding: utf-8 -*-

import os
import sqlite3

db_file = os.path.join(os.path.dirname(__file__), 'test.db')
if os.path.isfile(db_file):
    os.remove(db_file)
# 初始数据:
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
cursor.execute(
    'create table user(id varchar(20) primary key, name varchar(20), score int)')
cursor.execute(r"insert into user values ('A-001', 'Adam', 95)")
cursor.execute(r"insert into user values ('A-002', 'Bart', 62)")
cursor.execute(r"insert into user values ('A-003', 'Lisa', 78)")
cursor.close()
conn.commit()
conn.close()
# 第一种我想得到的写法
def get_score_in(low, high):
    conn = sqlite3.connect(db_file)
    cursor = conn.cursor()
    cursor.execute(r"select * from user order by score")
    values = cursor.fetchall()
    List = []
    for result in values:
        if result[2] >= low and result[2] <= high:
            List.append(result[1])
    cursor.close()
    conn.close()
    return List
' 返回指定分数区间的名字，按分数从低到高排序 '

# 第二种写法，感觉更好，直接用数据库排好序了，不知道sql语法的可以跟我上面那个一样
"""
def get_score_in(low, high):
    conn = sqlite3.connect(db_file)
    cursor = conn.cursor()
    cursor.execute(
        r"select * from user where score between ? and ? order by score", (low, high))
    values = cursor.fetchall()
    name = [x[1] for x in values]
    cursor.close()
    conn.close()
    return name
' 返回指定分数区间的名字，按分数从低到高排序 '
"""

# 测试:
assert get_score_in(80, 95) == ['Adam'], get_score_in(80, 95)
assert get_score_in(60, 80) == ['Bart', 'Lisa'], get_score_in(60, 80)
assert get_score_in(60, 100) == ['Bart', 'Lisa', 'Adam'], get_score_in(60, 100)
print('Pass')

